package com.ideal.blockchain.controller.deploy;

import com.ideal.blockchain.deploy.*;
import com.ideal.blockchain.dto.response.ResultInfo;
import com.ideal.blockchain.enums.ResponseCodeEnum;
import com.ideal.blockchain.service.deploy.AddChannelServiceImpl;
import com.ideal.blockchain.service.deploy.AddOrgServiceImpl;
import com.ideal.blockchain.service.deploy.HostServiceImpl;
import org.apache.tomcat.util.http.fileupload.util.Streams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.*;

import org.yaml.snakeyaml.Yaml;


@Slf4j
@RestController
@Component
@PropertySource("classpath:application.properties")
@RequestMapping("/deploy")
public class Generate {
    @Autowired
    private HostServiceImpl hostService;
    @Autowired
    private AddOrgServiceImpl addOrgService;
    @Autowired
    private AddChannelServiceImpl addChannelService;

    @Value("${script.deploypath}")
    private String deployPath;
    @Value("${script.genfilepath}")
    private String genfilePath;
    @Value("${script.address}")
    private String address;

    @RequestMapping("/generate")
    @ResponseBody
    public String GenConfig() throws FileNotFoundException {
        Generate configs = new Generate();
        YamlUtils ss=new YamlUtils();
//        Map<String, Object> tmpyy=getYamlToMap("deployment.yaml");
//        System.out.println(tmpyy.toString());
        try{
            File file = new File(genfilePath+"deployment.yaml");
            if(file.exists()) {
                file.delete();
            }
        }catch (Exception e){
            return e.getMessage();
        }

        try {
            // 1添加/修改主机列表
            List<Host> tmpHost = hostService.queryAll();
            Map<String, Object> tmpMark = new LinkedHashMap<>();
            String result = null;
            for (int i = 0; i < tmpHost.size(); i++) {
                Map<String, Object> tmpAA = new LinkedHashMap<>();
                tmpAA.put("ip", tmpHost.get(i).getIp());
                tmpAA.put("user", tmpHost.get(i).getName());
                tmpAA.put("password", tmpHost.get(i).getPassword());
                tmpMark.put(tmpHost.get(i).getMark(), tmpAA);
                result = ss.addProperty("hosts.pool", tmpMark, new FileInputStream(genfilePath + "templates.yaml"));
            }
            configs.WriteStringToFile(genfilePath + "deployment.yaml", result);

            // 2添加/修改组织列表
            List<Org1> tmpOrg = addOrgService.queryAllOrg();
            for (int i = 0; i < tmpOrg.size(); i++) {
                if (tmpOrg.get(i).getType().equals("orderer")) {
                    Map<String, Object> tmpBB = new LinkedHashMap<>();
                    tmpBB.put("name", "orderer");
                    tmpBB.put("domain", tmpOrg.get(i).getDomain());
//                tmpBB.put("country","CN");
//                tmpBB.put("province","Shanghai");
                    tmpBB.put("orderers", tmpOrg.get(i).getHosts().split(","));
                    result = ss.addProperty("fabric.ordererOrg", tmpBB, new FileInputStream(genfilePath + "deployment.yaml"));
                    configs.WriteStringToFile(genfilePath + "deployment.yaml", result);
                } else {
                    Map<String, Object> tmpCC = new LinkedHashMap<>();
//                tmpCC.put("country","CN");
//                tmpCC.put("province","Shanghai");
                    tmpCC.put("usersCount", 1);
                    tmpCC.put("peers", tmpOrg.get(i).getHosts().split(","));
                    result = ss.addProperty("fabric.peerOrgs." + tmpOrg.get(i).getName(), tmpCC, new FileInputStream(genfilePath + "deployment.yaml"));
                    configs.WriteStringToFile(genfilePath + "deployment.yaml", result);
                }
            }

            //3 添加/修改通道配置
            List<Channel1> tmpChannel = addChannelService.queryAllChannel();
            for (int i = 0; i < tmpChannel.size(); i++) {
                Map<String, Object> tmpDD = new LinkedHashMap<>();
                tmpDD.put("profile", "ZFConsortiumChannel");
                tmpDD.put("consortium", "ZFConsortium");
                tmpDD.put("orgs", tmpChannel.get(i).getOrgs().split(","));
                result = ss.addProperty("fabric.channels." + tmpChannel.get(i).getName(), tmpDD, new FileInputStream(genfilePath + "deployment.yaml"));
                configs.WriteStringToFile(genfilePath + "deployment.yaml", result);
            }
            return result;
        }catch (Exception e){
            return e.getMessage();
        }

    }

    public void WriteStringToFile(String filePath,String str) {
        try {
            FileOutputStream fos = new FileOutputStream(filePath);
            fos.write(str.getBytes());
            fos.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 将yaml配置文件转化成map
     * fileName 默认是resources目录下的yaml文件, 如果yaml文件在resources子目录下，需要加上子目录 比如：conf/config.yaml
     * @param fileName
     * @return
     */
    public static Map<String, Object> getYamlToMap(String fileName) {
        LinkedHashMap<String, Object> yamls = new LinkedHashMap<>();
        Yaml yaml = new Yaml();
        try {
            InputStream inputStream = new FileInputStream(fileName);
            yamls = yaml.loadAs(inputStream, LinkedHashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return yamls;
    }

    @RequestMapping("/deployFabric")
    @ResponseBody
    public ResultInfo DeployFabric(){
        try {
            String exe = "python";
            String[] cmdArr = new String[] { exe, deployPath,"--install","--virtual-host"};
            System.out.println("^^^^^^^^^^^^^^^^^^^^^"+Arrays.toString(cmdArr));
            Process process = Runtime.getRuntime().exec(cmdArr);
            WebSocketServer tmpSocket=new WebSocketServer();

//            try{
//                BufferedReader br = new BufferedReader(new FileReader("/opt/zpp/deploy/pylog.log"));
//            }catch (Exception e){
//                return "Error";
//            }
            new Thread() {
                public void run() {
//                    BufferedReader br = new BufferedReader(new InputStreamReader(in));
                    BufferedReader br = new BufferedReader(new
                            InputStreamReader(process.getInputStream()));
                    try {
                        String line;
                        while ((line = br.readLine()) != null) {
                            if (line != null){
                                tmpSocket.sendToUser(line,"123");
//                                sleep(10);
                            }
                        }
                    } catch (IOException e) {
                        tmpSocket.onClose();
                        e.printStackTrace();
                    }
                    finally{
                        try {
                            br.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            int res=process.waitFor();
            process.destroy();
//            tmpSocket.onClose();
            System.out.println("FFFFFFFFFFFFFFF"+res);
            return new ResultInfo(ResponseCodeEnum.SUCCESS, "部署区块链成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultInfo(ResponseCodeEnum.FAILURE, e.getMessage());
        }
    }

}
